﻿using JewererBasic.Classes;
using JewererBasic.Models;
using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Transactions;
using System.Web;

namespace JewererBasic.BO
{    
    public class StoneBO
    {        
        public static bool Add(STONE stone)
        {
            MSQDBEntities db = new MSQDBEntities();
            var query = from d in db.STONEs
                        where d.Id.Equals(stone.Id)
                        select d;
            if (query.Count() > 0)
                return false;
            stone.DayMake = DateTime.Now.Date;
            stone.IdCreater = CurrentUser.UserID;
            if (stone.Weight.HasValue)
            {
                stone.Weight = Math.Round(stone.Weight.Value, 3);
            }
            else
            {
                stone.Weight = 0;
            }
            db.STONEs.Add(stone);
            try
            {
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                // validation error
                return false;
            }
            return true;
        }

        public static bool Delete(string id)
        {
            MSQDBEntities db = new MSQDBEntities();
            var query=db.STONEs.Find(id);
            if(query!=null)
            {
                try{
                    db.STONEs.Remove(query);
                    db.SaveChanges();
                }
                catch(Exception ex)
                {
                    query.IsDeleted=1;
                    db.SaveChanges();
                    return true;
                }
            }
            return true;
        }

        public static bool Update(STONE stone)
        {
            MSQDBEntities db = new MSQDBEntities();
            var query = db.STONEs.Find(stone.Id);
            if (query != null)
            {
                query.Name = stone.Name;
                query.IsDeleted = -1;
                query.IdCreater = CurrentUser.UserID;
                query.Decription = stone.Decription;
                query.DayMake = DateTime.Now.Date;
                try
                {
                    db.SaveChanges();
                    return true;
                }
                catch (Exception ex)
                {
                    return false;
                }
            }
            return false;
        }

        public static List<STONE> Search(string id, string name)
        {
            MSQDBEntities db = new MSQDBEntities();
            var query = (from d in db.STONEs
                        where d.Id.Contains(id) && d.Name.Contains(name)
                        select d).ToList();
            return query;
        }

        public static List<STONE> Stones()
        {
            MSQDBEntities db = new MSQDBEntities();
            var query = from d in db.STONEs
                        where d.IsDeleted == -1
                        select d;
            return query.ToList();
        }

        public static bool Import(STONE_IMPORT stoneImport, List<STONE_IMPORT_DETAIL> details)
        {
            using (MSQDBEntities db = new MSQDBEntities())
            {
                // use transaction to prevent error on data.
                using (var scope = new TransactionScope())
                {
                    try
                    {
                        // add Stone_Import
                        stoneImport.IdCreater = CurrentUser.UserID;
                        stoneImport.DayMake = DateTime.Now.Date;
                        db.STONE_IMPORT.Add(stoneImport);
                        db.SaveChanges();

                        // add Detail Stone Import
                        for (int i = 0; i < details.Count; i++)
                        {
                            details[i].IdImport = stoneImport.Id;
                            details[i].Weight = Math.Round(details[i].Weight, 3);
                            db.STONE_IMPORT_DETAIL.Add(details[i]);
                        }
                        db.SaveChanges();
                        
                        // add weight and numb to stone
                        for (int i = 0; i < details.Count; i++)
                        {
                            var query = db.STONEs.Find(details[i].IdStone);
                            if (query == null)
                                return false;
                            query.Numb += details[i].Numb;
                            query.Weight += details[i].Weight;
                            if (query.Weight.HasValue)
                            {
                                query.Weight = Math.Round(query.Weight.Value, 3);
                            }
                        }
                        db.SaveChanges();                        
                        scope.Complete();
                    }
                    catch (Exception e)
                    {
                        return false;
                    }
                }
                return true;
            }
        }

        /// <summary>
        /// When creating bag, create BAG_STONE. 
        /// This function edits BAG_STONE by adding numb and weight
        /// </summary>
        /// <param name="idBag"></param>
        /// <param name="bagStones"></param>
        /// <returns></returns>
        public static bool ExportToBag(string idBag, int receiver, STONE_EXPORTBAG stone_exportBag, List<BAG_STONE> bagStones, List<ServiceStone> listReasons)
        {            
            using (MSQDBEntities db = new MSQDBEntities())
            {
                /*Sang modified*/
                /*This is new logic*/
                /*Started bag is allowed to export stone*/
                //BAG bag = db.BAGs.Find(idBag);
                //if (bag == null)
                //{
                //    ErrorLog.Instance.InternalErrors.Add("Can't find bag has id: " + idBag);
                //    return false;
                //}

                //if (bag.Finish == 0) // mean  this bag is starting
                //{
                //    /*Only bag in "Stone Service" process is allowed to export stone*/
                //    foreach (var bag_process_history in bag.BAG_PROCESS_HISTORY)
                //    {
                //        if (bag_process_history.Status !=0)
                //        {
                //            ErrorLog.Instance.InternalErrors.Add("This bag is not started!\r\nBag Id: "+idBag);
                //            return false;
                //        }
                //        if(ProcessBO.IsAllowedStoneExport(bag_process_history.IdProcess)==false)
                //        {
                //            ErrorLog.Instance.InternalErrors.Add("This bag is not in Stone Service process\r\nBag Id: " + idBag);
                //            return false;
                //        }
                //    }
                //}
                /*End Sang modified*/

                for (int i = 0; i < bagStones.Count; i++)
                {
                    bagStones[i].IdBag = idBag;
                }

                using (var scope = new TransactionScope())
                {
                    try
                    {
                        // CREATE STONE EXPORT
                        // create stone_exportbag and save to db
                        stone_exportBag.IdBag = idBag;
                        stone_exportBag.IdCreater = CurrentUser.UserID;
                        stone_exportBag.DayMake = DateTime.Now.Date;
                        stone_exportBag.IdReceiver = receiver;
                        db.STONE_EXPORTBAG.Add(stone_exportBag);
                        db.SaveChanges();
                        // create stone export bag detail and save to db
                        for (int i = 0; i < bagStones.Count; i++)
                        {
                            STONE_EXPORTBAGDETAIL sebd = new STONE_EXPORTBAGDETAIL();
                            sebd.IdExport = stone_exportBag.IdExport;
                            sebd.IdStone = bagStones[i].IdStone;
                            sebd.Numb = (int)bagStones[i].Numb;
                            sebd.Weight = Math.Round(bagStones[i].Weight, 3);
                            sebd.Reason = listReasons[i].Reason;
                            db.STONE_EXPORTBAGDETAIL.Add(sebd);
                        }
                        db.SaveChanges();

                        // ADD NUMB AND WEIGHT IN BAG STONE
                        for (int i = 0; i < bagStones.Count; i++)
                        {
                            var query = db.BAG_STONE.Find(idBag, bagStones[i].IdStone);
                            if (query == null)
                                throw new Exception("Can't find BAG_STONE, maybe you've not creating BAG_STONE properly when creating bag!");
                            query.Numb += bagStones[i].Numb;
                            query.Weight += bagStones[i].Weight;
                            query.Weight = Math.Round(query.Weight, 3);
                        }
                        db.SaveChanges();

                        // subtract in Stone
                        // add weight to bag
                        for (int i = 0; i < bagStones.Count; i++)
                        {
                            var query = db.STONEs.Find(bagStones[i].IdStone);
                            if (query != null)
                            {
                                query.Numb -= bagStones[i].Numb;
                                query.Weight -= bagStones[i].Weight;
                                if (query.Weight.HasValue)
                                {
                                    query.Weight = Math.Round(query.Weight.Value, 3);
                                }

                                // add weight to bag
                                BAG b = db.BAGs.Find(bagStones[i].IdBag);
                                b.Current_Weight = Math.Round(b.Current_Weight + bagStones[i].Weight, 3);
                            }
                        }
                        db.SaveChanges();
                        scope.Complete();
                    }
                    catch (Exception e)
                    {
                        ErrorLog.Instance.InternalErrors.Add("Error when saving Stone Export Bag data!\r\nNo change in database!");
                        return false;
                    }
                }
            }
            return true;
        }

        public static bool ExportToStaff(int idStaff, STONE_EXPORTSTAFF se, List<STONE_EXPORTSTAFFDETAIL> details)
        {
            using (MSQDBEntities db = new MSQDBEntities())
            {
                using (var scope = new TransactionScope())
                {
                    try
                    {
                        // create stone exportstaff
                        se.DayMake = DateTime.Now.Date;
                        se.IdCreater = CurrentUser.UserID;
                        se.IdStaff = idStaff;
                        db.STONE_EXPORTSTAFF.Add(se);
                        db.SaveChanges();
                        for (int i = 0; i < details.Count; i++)
                        {
                            details[i].IdExport = se.IdExport;
                            details[i].Weight = Math.Round(details[i].Weight, 3);
                            db.STONE_EXPORTSTAFFDETAIL.Add(details[i]);
                        }
                        db.SaveChanges();

                        // subtractStone
                        for (int i = 0; i < details.Count; i++)
                        {
                            var query = db.STONEs.Find(details[i].IdStone);
                            if (query != null)
                            {
                                query.Numb -= details[i].Numb;
                                query.Weight -= details[i].Weight;
                                if (query.Weight.HasValue)
                                {
                                    query.Weight = Math.Round(query.Weight.Value, 3);
                                }
                            }
                        }
                        db.SaveChanges();
                        scope.Complete();
                    }
                    catch (Exception ex)
                    {
                        return false;
                    }
                }
                return true;
            }
        }
              
        public static List<BAG_STONE> BagStones(string idBag)
        {
            MSQDBEntities db = new MSQDBEntities();
            var query = from d in db.BAG_STONE
                        where d.IdBag == idBag
                        select d;
            return query.ToList();
        }

        public static void Something()
        {

            using (MSQDBEntities ctx = new MSQDBEntities())
            {
               using (var scope = new TransactionScope())
               {
                   
                  scope.Complete();
               }
            }
        }

        public static List<HistoryStone> History(string idStone, DateTime? dateFrom, DateTime? dateTo, bool isImport, bool isExportBag, bool isExportStaff)
        {
            List<HistoryStone> result = new List<HistoryStone>();
            MSQDBEntities db = new MSQDBEntities();

            // get import history
            if (isImport == true)
            {
                var queryImport = from d in db.STONE_IMPORT
                                select d;

                if (dateFrom.HasValue)
                {
                    queryImport = queryImport.Where(d => d.DayMake >= dateFrom.Value);
                }
                if (dateTo.HasValue)
                {
                    queryImport = queryImport.Where(d => d.DayMake <= dateTo.Value);
                }

                var imports = queryImport.ToList();
                if (imports.Count > 0)
                {
                    foreach (var item in imports)
                    {
                        foreach (var stone in item.STONE_IMPORT_DETAIL)
                        {
                            if (String.IsNullOrEmpty(idStone) == true || stone.IdStone.Equals(idStone))
                            {
                                result.Add(new HistoryStone(item, stone));
                            }
                        }
                    }
                }
            }

            // get exportbag history
            if (isExportBag == true)
            {
                var queryExportBag = from d in db.STONE_EXPORTBAG
                                  select d;

                if (dateFrom.HasValue)
                {
                    queryExportBag = queryExportBag.Where(d => d.DayMake >= dateFrom.Value);
                }
                if (dateTo.HasValue)
                {
                    queryExportBag = queryExportBag.Where(d => d.DayMake <= dateTo.Value);
                }

                var exportBags = queryExportBag.ToList();
                if (exportBags.Count > 0)
                {
                    foreach (var item in exportBags)
                    {
                        foreach (var bag in item.STONE_EXPORTBAGDETAIL)
                        {
                            if (String.IsNullOrEmpty(idStone) == true || bag.IdStone.Equals(idStone))
                                result.Add(new HistoryStone(item, bag));
                        }
                    }
                }
            }

            // get exportstaff history
            if (isExportStaff == true)
            {
                var queryExportStaff = from d in db.STONE_EXPORTSTAFF
                                     select d;

                if (dateFrom.HasValue)
                {
                    queryExportStaff = queryExportStaff.Where(d => d.DayMake >= dateFrom.Value);
                }
                if (dateTo.HasValue)
                {
                    queryExportStaff = queryExportStaff.Where(d => d.DayMake <= dateTo.Value);
                }

                var exportStaffs = queryExportStaff.ToList();
                if (exportStaffs.Count > 0)
                {
                    foreach (var item in exportStaffs)
                    {
                        foreach (var staff in item.STONE_EXPORTSTAFFDETAIL)
                        {
                            if (String.IsNullOrEmpty(idStone) == true || staff.IdStone.Equals(idStone))
                                result.Add(new HistoryStone(item, staff));
                        }
                    }
                }
            }
            return result;
        }
    }
}